#!/usr/bin/python3
import os
import re

from models.Generator_Server_Code.Entity import Entity
from utils import String_Util, My_Util2


class Single_Verify:
    """
    单向数据流校验
    """

    def __init__(
        self,
        context,
        entity: Entity,
        column_name: str,
        sql_type: str,
        java_type: str,
        comment: str,
        not_null: bool,
    ) -> None:
        self.context = context
        self.entity = entity
        self.author: str = entity.author
        self.package: str = entity.package
        self.table_name: str = entity.table_name
        self.field_name: str = String_Util.entity_name(column_name)
        self.sql_type: str = sql_type
        self.java_type: str = java_type
        self.comment: str = comment
        self.not_null: bool = not_null
        self.prefix: str = self.table_name.split("_")[0].lower()
        self.suffix: str = String_Util.entity_name(
            "_".join(self.table_name.split("_")[1:])
        ).lower()
        if self.java_type == "String":
            self.max_length: int = re.findall(r"\d+", sql_type)[0]
        self.my_util2 = My_Util2.My_Util(self.context)

    def code_includes(self):
        includes = list()
        if self.java_type == "Currency":
            includes.append(f"""import {self.package}.internal.currency.Currency;""")
        if self.java_type == "NameInfo":
            includes.append(f"""import {self.package}.internal.i18n.NameInfo;""")
        includes.append(f"""import {self.package}.internal.validation.MyAssert;""")
        includes.append(f"""import {self.package}.internal.verification.IChecker;""")
        includes.append(f"""import org.springframework.stereotype.Component;""")
        if self.java_type == "BigDecimal":
            includes.append("import java.math.BigDecimal;")
        if self.java_type == "Date":
            includes.append("import java.util.Date;")
        includes = self.my_util2.sort_import_order(includes)
        return "\n".join(includes)

    def conditions(self):
        conditions = []
        column_name = self.field_name
        comment = self.comment
        if "；" in comment:
            comment = comment.split("；")[0]

        if self.not_null:
            if self.java_type == "String":
                max_length = self.max_length
                conditions.append(
                    f"""
        MyAssert.hasLength(value, "{comment}不能为空");"""
                )
                conditions.append(
                    f"""
        MyAssert.isTrue(value.length() <= {max_length}, "{comment}长度不能大于{max_length}位");"""
                )
        return "".join(conditions)

    def save_file(self, dir):
        _target_dir = os.path.join(dir, self.context["code_storage"]["root"], "checker")
        if not os.path.exists(_target_dir):
            os.makedirs(_target_dir)
        with open(
            os.path.join(
                _target_dir,
                "{}BO{}Checker.java".format(self.entity.name, self.field_name),
            ),
            mode="w",
            encoding="utf-8",
        ) as f:
            f.write(self.code())

    def code(self):
        entity_name = self.entity.name
        entity_comment = self.entity.comment
        author = self.author
        package = self.package
        field_name = self.field_name
        java_type = self.java_type
        comment = self.comment
        prefix = self.prefix
        suffix = self.suffix

        includes = self.code_includes()
        conditions = self.conditions()

        return f"""package {package}.{self.context["code_storage"]["root"]}.checker;

{includes}

/**
 * <p>
 * {entity_comment}-{comment}单向数据流校验器
 * </p>
 *
 * @author {author}
 */
@Component(value = "{entity_name}BO{field_name}Checker")
public class {entity_name}BO{field_name}Checker implements IChecker {"{"}

    @Override
    public void check(Object obj) {"{"}
        MyAssert.notNull(obj, "{comment}不能为空");
        {java_type} value = ({java_type}) obj;
        {conditions}
    {"}"}
{"}"}
"""
